#include <SFML/Network.hpp>
#include "../shared/network.hpp"
#include "ServerPlayer.hpp"
#include "server.hpp"

#include <iostream>
#include <vector>

using namespace std;

vector<class ServerPlayer> clients;

int main()
{
    sf::Randomizer rand;

    sf::SocketTCP Listener;
    sf::SelectorTCP Selector;
    if (!Listener.Listen(4567))
        return EXIT_FAILURE;

    Selector.Add(Listener);
    while (true)
    {
        unsigned int NbSockets = Selector.Wait();

        for (unsigned int i = 0; i < NbSockets; ++i)
        {
            sf::SocketTCP Socket = Selector.GetSocketReady(i);
            if (Socket == Listener)
            {
                sf::IPAddress Address;
                sf::SocketTCP Cl_sock;
                Listener.Accept(Cl_sock, &Address);
                sf::Int32 pid = rand.Random(0,20000000);
                std::cout << "Client connected ! (" << Address << ")" << " (" << pid << ")" << std::endl;

                ServerPlayer cl;
                cl.Sock = Cl_sock;
                cl.Ip = Address;
                cl.SetPid(pid);
                cl.pos = sf::Vector2f(0,0);
                cl.velocity = sf::Vector2f(0,0);
                cl.angle = 0;
                clients.push_back(cl);
                Selector.Add(Cl_sock);

                broadcast(PK_SRV_PLCONNECT(cl.GetPid()),clients);
                for(vector<class ServerPlayer>::iterator iter = clients.begin(); iter != clients.end(); ++iter)
                {
                    if(iter->GetPid() != pid)
                    {
                        sf::Packet connect = PK_SRV_PLCONNECT(iter->GetPid());
                        Cl_sock.Send(connect);
                    }
                    sf::Packet pos = PK_SRV_PLPOS(iter->GetPid(), iter->pos.x, iter->pos.y, iter->velocity.x, iter->velocity.y, iter->angle);
                    Cl_sock.Send(pos);
                }
            }
            else
            {
                sf::Packet Packet;
                if (Socket.Receive(Packet) == sf::Socket::Done)
                {
                    sf::Uint8 type;
                    type = Packet_Type(Packet);
                    if(type == PKTYPE_CLT_PLMOVE)
                    {
                        struct PKCONTENT_CLT_PLMOVE pkcontent;
                        pkcontent = PK_CLT_PLMOVE(Packet);
                        ServerPlayer& cl = GetServerPlayerBySocket(Socket,clients);

                        sf::Vector2f pos(pkcontent.x,pkcontent.y);
                        sf::Vector2f vel(pkcontent.vel_x,pkcontent.vel_y);
                        float angle = pkcontent.rotation;

                        cl.angle = angle;
                        cl.pos = pos;
                        cl.velocity = vel;
                        broadcast(PK_SRV_PLPOS(cl.GetPid(), pos.x, pos.y, vel.x, vel.y, angle),clients);
                    }
                }
                else
                {
                    sf::Int32 pid = GetServerPlayerBySocket(Socket,clients).GetPid();
                    RemoveFromVector(Socket,clients);
                    Selector.Remove(Socket);
                    broadcast(PK_SRV_PLDISCONNECT(pid),clients);
                }
            }
        }
    }
}
